package com.tzbank.wisdom.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Future;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.tzbank.esb.util.EsbConsumerUtil;
import com.tzbank.redis.RedisUtils;
import com.tzbank.utils.CodeUtil;
import com.tzbank.utils.ResultCode;
import com.tzbank.utils.ResultUtil;
import com.tzbank.wisdom.dao.MyCardPackageMapper;
import com.tzbank.wisdom.service.MyCardPackageService;
import com.tzbank.wisdom.service.SaveService;
import com.tzbank.wisdom.utils.BusinessConstant;
import com.tzbank.wisdom.utils.RequestMap;
import com.tzbank.wisdom.utils.ThreadPoolFactory;
import com.tzbank.wisdom.utils.TransCodeEnum;

import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

@Service
@Slf4j
public class MyCardPackageServiceImpl implements MyCardPackageService {

	@Autowired
	private SaveService saveService;

	@Autowired
	private MyCardPackageMapper myCardPackageMapper;



	@SuppressWarnings("unchecked")
	@Override
	public Map<String, Object> myCardList(Map<String, String> reqParams) {

		String clientSeqNo = reqParams.get("clientSeqNo");
		Map<String, Object> userInfo = RedisUtils.getUserInfo(clientSeqNo);
		if (userInfo == null) {
			return ResultUtil.resultMap("请重新登录", ResultCode.RESUTL_CODE_FAILURE.code(), null);
		}

		JSONArray acctArray = JSONArray.fromObject(userInfo.get("acctArray"));

		Map<String, Object> resultMap = this.saveService.getAcctList(reqParams);
		JSONObject data = JSONObject.fromObject(resultMap.get("data"));

		JSONArray listArray = data.getJSONArray("listArray");

		int index = 0;

		Iterator<JSONObject> iteratorAcct = acctArray.iterator();
		while (iteratorAcct.hasNext()) {
			JSONObject acctJson = iteratorAcct.next();
			Iterator<JSONObject> iteratorList = listArray.iterator();
			while (iteratorList.hasNext()) {
				JSONObject listJson = iteratorList.next();
				// 找相同卡片获取余额
				if (listJson.getString("acctNo").equals(acctJson.getString("acctNo"))) {
					// iteratorAcct.next().put("actualBal", listJson.getString("actualBal"));
					acctArray.remove(index);
					acctJson.put("balance", listJson.getString("balance"));
					acctArray.add(index, acctJson);
					index++;
					break;
				} else {
					acctJson.put("balance", "");
				}
				index++;
			}
		}

		JSONObject dataJSON = new JSONObject();
		dataJSON.put("acctArray", acctArray);

		return ResultUtil.resultMap(CodeUtil.CODE_200.getName(), CodeUtil.CODE_200.getCode(), dataJSON);
	}

	/**
	 *  我的卡包-添加卡片 需要一同做 下挂操作
	 */
	@SuppressWarnings("unchecked")
	public Map<String, Object> addCard(Map paramMap) {
	
		Map<String, String>  params = new HashMap<String, String>();
		params.putAll(paramMap);
		
		//添加之前，先去本地库进行查询判断	
		String acctNo =(String) paramMap.get("acctNo");
		Map _map = new HashMap<>();
		_map.put("acct_no", acctNo);
		int count = myCardPackageMapper.queryCardCount(_map);
		if(count>0) {
			return	ResultUtil.resultMap(CodeUtil.CODE_10020.getName(), CodeUtil.CODE_10020.getCode(), null);
		}
		
		List accoutList = getHangingAccountList(params);		
		if (accoutList == null || accoutList.size()==0) {
			return	ResultUtil.resultMap("没有可挂账户", CodeUtil.CODE_10000.getCode(), null);
		}

	/*	Map<String, Object> maps = commonService.verifyTransPassword(paramMap);
		if (!CodeUtil.CODE_200.getCode().equals(maps.get("code"))) {
			log.info("校验交易密码 响应结果:{}", maps.get("msg"));
			return maps;
		}*/
		Map<String, Object> m = new HashMap<String, Object>();
		for (Map.Entry<String, String> entry : params.entrySet()) {
			m.put(entry.getKey(), entry.getValue());
		}
		final CountDownLatch latch = new CountDownLatch(accoutList.size());
		List<Future<Map<String, Object>>> addResult = new ArrayList<Future<Map<String, Object>>>();// 所有的返回结果	
		for (int i = 0; i < accoutList.size(); i++) {
			Map map = (Map) accoutList.get(i);		
			m.put("count", String.valueOf(i));
			m.put("acctType", map.get("acctType"));
			m.put("acctNo", map.get("acctNo"));
			m.put("acctAlias", "");
			Future<Map<String, Object>> mapFuture = (Future<Map<String, Object>>) ThreadPoolFactory.getThreadPool()
					.submit(new Callable<Object>() {
						@Override
						public Object call() throws Exception {
							return goAddCard(m);
						}
					});					
			addResult.add(mapFuture);
		}
		Map<String, Object> resultMap = new HashMap<String, Object>(); 
		Map<String, Object> result = new HashMap<String, Object>(); 
		try {			
			/**
			 * 等异步完成账号下所有子账户的下挂操作后，查询出所有卡信息，更新Redis
			 */
			Future<Map<String, Object>> resultFuture = addResult.get(addResult.size()-1);
				result = (Map<String, Object>) resultFuture.get().get("data");
				resultMap.put("queryResult",result);			
			System.out.println("================================>"+addResult.size());			
		//	boolean isAllDone = latch.await(500000, TimeUnit.MILLISECONDS);
		} catch (Exception e) {
			e.printStackTrace();
		} 	
	return  ResultUtil.resultMap("成功", ResultCode.RESULT_CODE_SUCCESS.code(), null );
	}
	

	public Map<String, Object> goAddCard(Map<String, Object> reqParams) {
		log.info("个人网银签约账户加挂 请求参数:" + JSON.toJSONString(reqParams));
		Map<String, Object> inputMap = new HashMap<>();
		Map<String, Object> reqSysHead = new HashMap<>();
		String clientSeqNo = reqParams.get("clientSeqNo").toString();
		String acctType = reqParams.get("acctType").toString();
		String acctNo = reqParams.get("acctNo").toString();
		String acctAlias = reqParams.get("acctAlias").toString();
		String tranPassword = reqParams.get("tranPassword").toString();
		reqSysHead = RequestMap.getReqSysHead(TransCodeEnum.CARD_PACKAGE_ADD.getServiceCode(),
				TransCodeEnum.CARD_PACKAGE_ADD.getServiceSence(), "0110");
		inputMap = RequestMap.getInputMap(reqParams);
		Map<String, Object> userMap = RequestMap.getInputUserInfo(clientSeqNo);
		if (userMap.get("clientNo") == null) {
			return userMap;
		}
		inputMap.putAll(userMap);
		inputMap.put("sysHead", reqSysHead);
		inputMap.put("acctType", acctType); // 卡类型
		inputMap.put("acctNo", acctNo); // 卡类型
		inputMap.put("acctAlias", acctAlias); // 卡别名
		inputMap.put("tranPassword", tranPassword); // 交易密码
		log.info("个人网银签约账户加挂 请求开始...");
		Map<String, Object> result = EsbConsumerUtil.clientRequest(inputMap);
		log.info("个人网银签约账户加挂 请求结束"+reqParams.get("count")+" 响应结果：{}", result);
		if (CodeUtil.CODE_200.getCode().equals(result.get("code"))) {
			//将下挂成功的卡，保存入库
			Map map = new HashMap<>();
			map.put("client_no", clientSeqNo);
			map.put("acct_no", acctNo.substring(0, acctNo.indexOf("-")));
			map.put("acct_type", acctType);
			map.put("acct_alias", acctAlias);
			map.put("bank_name", "");		
			map.put("bank_code", "");					
			int count = myCardPackageMapper.queryCardCount(map);
				if(count<1) {
					 	myCardPackageMapper.addCard(map);
				}
			return ResultUtil.resultMap("成功", ResultCode.RESULT_CODE_SUCCESS.code(), result.get("data"));
		}
		return ResultUtil.resultMap(result.get("msg").toString(), ResultCode.RESUTL_CODE_FAILURE.code(), null);
	}
	
	
	
	/***
	 * 查询已经下挂的卡
	 * @param reqParams
	 * @return
	 */
	public Map<String, Object> queryCard(Map<String, String> reqParams) {
		
			Map<String, Object> result = new HashMap<>();		
			String client_no = reqParams.get("clientSeqNo");
			List<Map> list= 	myCardPackageMapper.queryCard(client_no);
			Map<String, Object> resultSave =saveService.getAcctList(reqParams);
		    Map<String, Object> data = (Map<String, Object>) resultSave.get("data");
            List listArray = (List) data.get("listArray");	
        	List<Map>resultList= new ArrayList<>();
			for(int i =0 ;i<list.size();i++) {
					Map<String,String> map = (Map) list.get(i);
					String acct_no = map.get("acct_no");
					String acct_alias = map.get("acct_alias");
					double balance= 0.00;
					Map<String, Object> msg = new HashMap<>();
						for (int j =0;j<listArray.size();j++){
						Map<String,String> mapSave = (Map) listArray.get(j);
								String acctNo = mapSave.get("acctNo");
								if(acctNo.contains(acct_no)) {
									 balance +=Double.parseDouble(mapSave.get("balance")) ;
									 msg.put("acctNo",acct_no );
									 msg.put("acctAlias",acct_alias );
									 msg.put("acctName",mapSave.get("acctName") )	;
									 msg.put("certNo",mapSave.get("certNo") )	;
									 msg.put("acctLevel",mapSave.get("acctLevel") )	;
									 msg.put("cardAcctType",mapSave.get("cardAcctType") )	;									 
									 msg.put("openBranch",mapSave.get("openBranch") )	;
								}
						}
						msg.put("balance", balance);
						resultList.add(msg);
			}			
			result.put("queryResult", resultList);					
			return ResultUtil.resultMap(CodeUtil.CODE_200.getName(), CodeUtil.CODE_200.getCode(), result);
	}
	
	
	/**
	 * 下挂账户验证 个人网银可加挂列表查询
	 */
	@SuppressWarnings("null")
	public List getHangingAccountList(Map<String, String> reqBody) {
		// 组装入参Map
		List resultList = new ArrayList();
		Map<String, Object> inputMap = new HashMap<String, Object>();
		Map<String, Object> reqSysHead = RequestMap.getReqSysHead("11003000017", "05", "",
				BusinessConstant.SOURCRE_TYPE_PMBBS);
		Map<String, Object> userMap = RequestMap.getInputUserInfo((String) reqBody.get("clientSeqNo"));
		if (userMap.get("clientNo") == null) {
			return null;
		}
		Map<?, ?> acclist = RedisUtils.getUserInfo(reqBody.get("clientSeqNo"));
		if (acclist != null) {
			List list = (List) acclist.get("acctArray");
			List newList = new ArrayList();
			for (int i = 0; i < list.size(); i++) {
				Map m = (Map) list.get(i);
				Map newMap = new HashMap();
				newMap.put("acctNo", m.get("acctNo"));// 账号
				newMap.put("acctSerialNo", m.get("acctSerialNo"));// 账户序号
				newMap.put("acctAlias", m.get("acctAlias"));// 账户别名
				newMap.put("branchType", m.get("acctType"));
				newMap.put("openOrgan", m.get("openBranch"));
				newList.add(newMap);
			}
			inputMap.put("globalId", acclist.get("globalId"));// 证件号码
			inputMap.put("globalType", acclist.get("globalType"));// 证件类型
			inputMap.put("listArray", newList);

		}
		inputMap.put("bussName", "TransJnlsQry");
		inputMap.put("userNo", userMap.get("eUserNo"));
		inputMap.put("eUserNo", userMap.get("eUserNo"));
		reqSysHead.putAll(userMap);
		// 调用核心计价因子报文头入参
		inputMap.put("sysHead", reqSysHead);
		// inputMap.put("logonType", "R");//登录方式
		inputMap.put("sendBranchId", "");// 发送方机构标识码inputMap.put("listArray", list);
		inputMap.put("clientIp", reqBody.get("ip"));// 客户端ip
		inputMap.put("ip", "");// IP地址
		inputMap.put("userId", userMap.get("userId"));// IP地址
		Map<String, Object> data = null;
		Map<String, Object> result = EsbConsumerUtil.clientRequest(inputMap);

	
		if (!CodeUtil.CODE_200.getCode().equals(result.get("code"))) {
			return null;
		}
		
		Map<String, Object> resultData = (Map<String, Object>) result.get("data");
		resultList = (List) resultData.get("queryResultArray");// 得到的可挂账户 的列表
		String acctNo = reqBody.get("acctNo");// 页面传过来的参数
		List backList = new ArrayList();// 过滤的卡号 得到子卡
		for (int i = 0; i < resultList.size(); i++) {
			Map<String, Object> map = (Map<String, Object>) resultList.get(i);
			String map_acctNo=(String) map.get("acctNo");
			
			if (map_acctNo.contains(acctNo)) {
				
				backList.add(map);
			}
		}
		return backList;
	}
	
	@Override
	public Map<String, Object> deleteCard(Map<String, Object> reqParams) {

		log.info("个人网银签约账户解挂 请求参数:" + JSON.toJSONString(reqParams));

		Map<String, Object> inputMap = new HashMap<>();
		Map<String, Object> reqSysHead = new HashMap<>();

		String clientSeqNo = reqParams.get("clientSeqNo").toString();
		String acctType = reqParams.get("acctType").toString();
		String acctNo = reqParams.get("acctNo").toString();
		// String tranPassword = reqParams.get("tranPassword").toString();

		reqSysHead = RequestMap.getReqSysHead(TransCodeEnum.CARD_PACKAGE_DELETE.getServiceCode(),
				TransCodeEnum.CARD_PACKAGE_DELETE.getServiceSence(), "0110");
		inputMap = RequestMap.getInputMap(reqParams);

		Map<String, Object> userMap = RequestMap.getInputUserInfo(clientSeqNo);
		if (userMap.get("clientNo") == null) {
			return userMap;
		}

		inputMap.putAll(userMap);
		inputMap.put("sysHead", reqSysHead);// 报文头
		inputMap.put("acctType", acctType);// 账户类型
		inputMap.put("acctNo", acctNo);// 账号
		// inputMap.put("tranPassword", tranPassword); // 交易密码;

		log.info("个人网银签约账户解挂 请求开始...");
		Map<String, Object> result = EsbConsumerUtil.clientRequest(inputMap);
		log.info("个人网银签约账户解挂 请求结束 响应结果：{}", result);
		if (CodeUtil.CODE_200.getCode().equals(result.get("code"))) {
			return ResultUtil.resultMap("成功", ResultCode.RESULT_CODE_SUCCESS.code(), result.get("data"));
		}
		return ResultUtil.resultMap(result.get("msg").toString(), ResultCode.RESUTL_CODE_FAILURE.code(), null);
	}


}
